package org.fhm.zdte.client.cmd;

import org.fhm.substrate.annotation.Component;
import org.fhm.substrate.annotation.Setup;
import org.fhm.substrate.service.LoggerHandler;
import org.fhm.substrate.standard.ILogger;
import org.fhm.zdte.client.ability.IIsOnline;
import org.fhm.zdte.client.api.ClientApi;
import org.fhm.zdte.client.exception.ClientException;
import org.fhm.zdte.common.ability.IGetIdentification;
import org.fhm.zdte.common.constant.protocol.ResponseMessageType;
import org.fhm.zdte.common.pojo.Address;
import org.fhm.zdte.common.pool.ThreadPoolFactory;
import org.fhm.zdte.common.protocol.AbstractMessageStandard;
import org.fhm.zdte.common.service.api.CommonThreadManager;

import java.util.concurrent.atomic.AtomicBoolean;

/**
 * Oline command processor.
 *
 * @author 谭波
 * @since 2023/11/6
 */
@Component("ONLINE")
public class OnlineClientCmd extends AbstractClientCmd implements IIsOnline, IGetIdentification {

    public static String SERVER_IDENTIFICATION;
    private static String CLIENT_IDENTIFICATION;
    private final AtomicBoolean isOnline = new AtomicBoolean(false);
    private final ILogger logger = LoggerHandler.getLogger(OnlineClientCmd.class);
    @Setup
    private ThreadPoolFactory threadPoolFactory;

    @Setup
    private ClientApi clientApi;


    @Override
    public void receiveCmd(Address address, AbstractMessageStandard message) {
        if (abstractMessageMonitor.isAck(message)) {
            if (iThreadManager.notify(CommonThreadManager.ONLINE_CLIENT_CONDITION)) {
                if (!isOnline.get()) {
                    boolean flag;
                    do {
                        flag = isOnline.compareAndSet(isOnline.get(), true);
                    } while (!flag);
                    CLIENT_IDENTIFICATION = message.getTo();
                    logger.info("your identification is {}", CLIENT_IDENTIFICATION);
                    SERVER_IDENTIFICATION = message.getFrom();
                    logger.info("the launch was successful, the identification of server side is {}", SERVER_IDENTIFICATION);
                }
            }
        }
        if (abstractMessageMonitor.isFailMessage(message)) {
            if (isOnline.get()) {
                synchronized (isOnline) {
                    if (isOnline.get()) {
                        boolean flag;
                        try {
                            clientApi.clientOnline();
                            do {
                                flag = isOnline.compareAndSet(isOnline.get(), true);
                            } while (!flag);
                        } catch (ClientException e) {
                            logger.info("reconnection exception：{}", e.getMessage());
                            logger.info(
                                    ResponseMessageType
                                            .getResponseDescByByte(
                                                    message.getResponseMessageType()
                                            )
                            );
                            do {
                                flag = isOnline.compareAndSet(isOnline.get(), false);
                            } while (!flag);
                        }
                    }
                }
            }
        }
    }

    @Override
    public boolean isOnline() {
        return isOnline.get();
    }

    @Override
    public String getIdentification() {
        return CLIENT_IDENTIFICATION;
    }
}
